<cfcomponent output="false">
	<cfset $ = application.helpers />
	<cfset $service = application.s />

	<!--- --->
	
	<cffunction name="getPaymentAccounts" access="public" output="false" returntype="query">
		
		<cfreturn application.g.paymentGateway.getPaymentAccounts(session.user.id) />

	</cffunction>
	
	<!--- --->
	
	<cffunction name="getPaymentMethods" access="public" output="false" returntype="query">
		<cfargument name="code" required="false" default="" />
		<cfargument name="id" required="false" default="" />
		
		<cfreturn application.g.paymentGateway.getPaymentMethods(argumentCollection=arguments) />

	</cffunction>
	
	<!--- --->
	
	<cffunction name="savePaymentAccount" access="public" output="false" returntype="struct">
		<cfargument name="payment_method_id" required="true" />
		<!--- cc args --->
		<cfargument name="name" required="false" />
		<cfargument name="number" required="false" />
		<cfargument name="month" required="false" />
		<cfargument name="year" required="false" />
		<cfargument name="cvv" required="false" />
		<!--- ach args --->
		<cfargument name="account_type" required="false" />
		<cfargument name="routing_number" required="false" />
		<cfargument name="account_number" required="false" />
		<!--- common args --->
		<cfargument name="card_name" required="true" />
		<cfargument name="address_1" required="true" />
		<cfargument name="address_2" required="true" />
		<cfargument name="city" required="true" />
		<cfargument name="state_id" required="true" />
		<cfargument name="zip" required="true" />
		<!--- if not logged in --->
		<cfargument name="email" required="false" default="" />
		
		<cfset var local = {} />
		
		<cfset local.paymentMethod = getPaymentMethods(id=arguments.payment_method_id) />
		<cfset local.paymentAccount = {} />
		<cfset local.paymentAccount.id = "" />
		<cfset local.paymentAccount.user_id = session.user.id />
		<cfset local.paymentAccount.table = "payment_account" />
		<cfset local.paymentAccount.payment_method_id = arguments.payment_method_id />
		<cfset local.paymentAccount.name = arguments.card_name />
		
		<cfif local.paymentMethod.code eq 'auth.net.cc'>
			<cfset local.paymentAccount.last_four_digits = right(arguments.number,4) />
		<cfelseif local.paymentMethod.code eq 'auth.net.ach'>
			<cfset local.paymentAccount.last_four_digits = right(arguments.account_number,4) />
		</cfif>
		
		<cfset local.response = {} />
		<cfset local.response.success = true />
		<cfset local.response.message = "" />
		<cfset local.paymentAccount.vendor_reference_id = '12345' />
		
		<!--- simulate vendor failure --->
		<cfif local.paymentAccount.last_four_digits mod 2 eq 0>
			<cfset local.response.success = false />
			<cfset local.response.message = "card number is not odd" />
		</cfif>
		
		<cfif local.response.success>
			<cfset local.response.message = $.database.save(argumentCollection=local.paymentAccount) />
		</cfif>
		
		<cfreturn local.response />

	</cffunction>
	
	<!--- --->
	
	<cffunction name="savePaymentPlan" access="public" output="false" returntype="boolean">
		<cfargument name="fundID" required="true" />
		<cfargument name="amount" required="true" />
		<cfargument name="date" required="true" />
		<cfargument name="end_date" required="true" />
		<cfargument name="installments" required="true" />
		<cfargument name="total_amount" required="true" />
		<cfargument name="message" required="true" />
		<!--- radios with fundID --->
		<cfargument name="anonymous" required="false" />
		<cfargument name="frequency" required="false" />
		<cfargument name="limit" required="false" />
		<cfargument name="payment_account_id" required="false" />
		
		<cfset var local = {} />
		<cfset local.fund = $service.fundSErvice.getIDByFundID(arguments.fundID) />
		<cfset local.process_payment = false />
		
		<!--- decide whether an initial payment will be processed as well --->
		<cfif arguments.date eq $.date.getDate()>
			<cfset local.process_payment = true />
		</cfif>
		
		<cfif arguments.amount eq "" or arguments.amount lte 0>
			<cfthrow message="invalid amount $#arguments.amount#" />
		</cfif>
		
		<cfif local.fund.recordcount neq 1>
			<cfthrow message="#local.fund.recordcount# fund(s) matched by this key #arguments.fundID#" />
		</cfif>
		
		<!--- set arguments by fundID --->
		<cfset arguments.anonymous = arguments['anonymous_#arguments.fundID#'] />
		<cfset arguments.frequency = arguments['frequency_#arguments.fundID#'] />
		<cfset arguments.limit = arguments['limit_#arguments.fundID#'] />
		<cfset arguments.payment_account_id = arguments['payment_account_id_#arguments.fundID#'] />
		
		<cfset local.payment_plan = {} />
		<cfset local.payment_plan.table="payment_plan" />
		<cfset local.payment_plan.id = "" />
		<cfset local.payment_plan.fund_id = local.fund.id />
		<cfset local.payment_plan.installment_amount = arguments.amount />
		<cfset local.payment_plan.user_id = session.user.id />
		<cfset local.payment_plan.payment_account_id = arguments.payment_account_id />
		<cfset local.payment_plan.start_date = arguments.date />
		<cfset local.payment_plan.frequency_id = arguments.frequency />
		<cfset local.payment_plan.boundary_id = arguments.limit />
		<cfset local.payment_plan.anonymous = arguments.anonymous />
		
		<cfif arguments.limit eq 1><!--- installments --->
			<cfset local.payment_plan.installments = arguments.installments />
		<cfelseif arguments.limit eq 2><!--- total --->
			<cfset local.payment_plan.amount = arguments.total_amount />
		<cfelseif arguments.limit eq 3><!--- end date --->
			<cfset local.payment_plan.end_date = arguments.end_date />
		</cfif>
		
		<cfif arguments.limit eq 1 and arguments.installments eq 1>
			<cfset local.payment_plan.single_payment eq 1 />
		</cfif>
		
		<cfset local.planID = $.database.save(argumentCollection=local.payment_plan) />

		<cfif local.process_payment>
			<!--- processPlanPayment --->
			<cfset processPayment(
				fundID=local.fund.id,
				userID=session.user.id,
				amount=arguments.amount,
				paymentPlanID=local.planID,
				paymentAccountID=arguments.payment_account_id
			) />
		</cfif>
		
		<cfreturn true />

	</cffunction>
	
	<!--- --->
	
	<cffunction name="getFrequencies" access="public" output="false" returntype="query">
		
		<cfreturn application.g.paymentGateway.getFrequencies(argumentCollection=arguments) />

	</cffunction>
	
	<!--- --->
	
	<cffunction name="getBoundaries" access="public" output="false" returntype="query">
		
		<cfreturn application.g.paymentGateway.getBoundaries(argumentCollection=arguments) />

	</cffunction>
	
	<!--- --->
	
	<cffunction name="getPaymentPlans" access="public" output="false" returntype="query">
		<cfargument name="fundID" required="false" default="" />
		<cfargument name="userID" required="true" /> 
		<cfargument name="ID" required="false" default="" />
		
		<cfreturn application.g.paymentGateway.getPaymentPlans(argumentCollection=arguments) />

	</cffunction>
	
	<!--- --->
	
	<cffunction name="processPayment" access="public" output="false" returntype="struct">
		<cfargument name="fundID" required="true" />
		<cfargument name="userID" required="true" />
		<cfargument name="amount" required="true" />
		<cfargument name="paymentPlanID" required="false" default="" />
		<cfargument name="paymentAccountID" required="true" default="" />
		
		<cfset var local = {} />
				
		<cfset local.paymentAccount = getPaymentAccountByID(arguments.paymentAccountID) />
		<!--- TODO: payment method to choose processing method --->
		
		<cfset local.response = {} />
		<cfset local.response.success = true />

		<cftry>
			<cfset local.processorResponse = {} />
			<cfset local.processorResponse.success = true />
			
			<cfif local.processorResponse.success>
				<cfset local.payment_status_code = 'pending' />
			<cfelse>
				<cfset local.payment_status_code = 'declined' />
			</cfif>
					
			<cfset local.payment_status = application.g.paymentGateway.getPaymentStatuses(code=local.payment_status_code) />
			
			<cfset local.payment = {} />
			<cfset local.payment.id = "" />
			<cfset local.payment.table = "payment" />
			<cfset local.payment.fund_id = arguments.fundID />
			<cfset local.payment.amount = arguments.amount />
			<cfset local.payment.user_id = arguments.userID />
			<cfset local.payment.cleared_date = "" />
			<cfset local.payment.payment_account_id = arguments.paymentAccountID />
			<cfset local.payment.payment_plan_id = arguments.paymentPlanID />
			<cfset local.payment.payment_status_id = local.payment_status.id />
			
			<cfset local.paymentID = $.database.save(argumentCollection=local.payment) />
			
			<cfset local.paymentActivity = {} />
			<cfset local.paymentActivity.id = "" />
			<cfset local.paymentActivity.table = "payment_activity" />
			<cfset local.paymentActivity.amount = arguments.amount />
			<cfset local.paymentActivity.payment_id = local.paymentID />
			
			<cfset local.paymentActivityID = $.database.save(argumentCollection=local.paymentActivity) />
			<cfcatch>
				<cfset local.response.success = false />
				<cfset local.response.message = cfcatch.message />
			</cfcatch>
		</cftry>
		
		<cfreturn local.response />

	</cffunction>
	
	<!--- --->
	
	<cffunction name="getPaymentAccountByID" access="public" output="false" returntype="query">
		<cfargument name="id" required="true" />
		
		<cfreturn application.g.paymentGateway.getPaymentAccountByID(argumentCollection=arguments) />
	
	</cffunction>
	
	<!--- --->
	
	<cffunction name="deletePaymentPlan" access="public" output="false" returntype="string">
		<cfargument name="paymentPlanID" required="true" />
		
		<cfset var local = {} />
		
		<cfset local.paymentPlan = getPaymentPlans(id=arguments.paymentPlanID,userID=session.user.id) />
		
		<cfif $.valid.id(local.paymentPlan.payment_id)> <!--- has payments = stop the plan --->
			<cfset $.database.save(
				id=arguments.paymentPlanID,
				table="payment_plan",
				end_date=$.date.getDate(),
				ended=1
			) />
		<cfelse>
			<cfset $.database.delete(table="payment_plan",id=arguments.paymentPlanID) />
		</cfif>
		
		<cfreturn trim(local.paymentPlan.fund_ID) />
	
	</cffunction>
	
	<!--- --->
	
	<cffunction name="cancelPayment" access="public" output="false" returntype="string">
		<cfargument name="paymentID" required="true" />
		
		<cfset var local = {} />
		
		<cfset local.payment = getPaymentByID(id=arguments.paymentID,userID=session.user.id) />
		<cfset local.payment_status = application.g.paymentGateway.getPaymentStatuses(code='cancelled') />
		
		<cfif local.payment.payment_status_name eq 'pending'>
			<cfset $.database.save(
				table="payment",
				id=local.payment.id,
				payment_status_id=local.payment_status.id
			) />
		</cfif>
		
		<cfreturn trim(local.payment.fund_ID) />
	
	</cffunction>
	
	<!--- --->
	
	<cffunction name="getPaymentByID" access="public" output="false" returntype="query">
		<cfargument name="id" required="true" />
		
		<cfset var local = {} />
		
		<cfreturn application.g.paymentGateway.getPaymentByID(argumentCollection=arguments) />
	
	</cffunction>
	
	<!--- --->

</cfcomponent>